<?php
/* [DoYouHaoBaby!] (C)Dianniu From 2010.
   Gtk接口($)*/

!defined('DYHB_PATH') && exit;

class DGtk{

	static private $_arrBackgroupWorkCallback;
	static private $_arrBackgroupWorkArgvs;
	static private $_bBlocking=false;
	static private $_oMapItemToData;

	static public function messageDialog($sLabel,$sMessageTitle='',$nDialogType=Gtk::MESSAGE_INFO,$nButtonFlags=Gtk::BUTTONS_OK,$nDialogFlags=3,GtkWidget $oParentWidget=null){
		$oDialog=new GtkMessageDialog($oParentWidget,$nDialogFlags,$nDialogType,$nButtonFlags,$sMessageTitle);
		if(!empty($sLabel)){// 如果设置了$sLabel标注
			$oDialog->set_markup($sLabel);
		}
		if(empty($sMessageTitle)){// 设置对话框标题
			$sMessageTitle='DoYouHaoBaby MessageDialog';
		}
		$oDialog->set_title($sMessageTitle);
		$oDialog->set_position(Gtk::WIN_POS_CENTER);// 设置对话框位置
		$nRet=$oDialog->run();
		$oDialog->destroy();// 销毁
		return $nRet;
	}

	static public function M($sLabel,$sMessageTitle='',$nDialogType=Gtk::MESSAGE_INFO,$nButtonFlags=Gtk::BUTTONS_OK,$nDialogFlags=3,GtkWidget $oParentWidget=null){
		$arrArgvs=func_get_args();
		return call_user_func_array(array(__CLASS__,'messageDialog'),$arrArgvs);
	}

	static public function confirmDialog($sLabel,$sMessageTitle='',$nDialogFlags=3,GtkWidget $oParentWidget=null){
		 return(self::messageDialog($sLabel,$sMessageTitle,Gtk::MESSAGE_QUESTION,Gtk::BUTTONS_YES_NO,$nDialogFlags,$oParentWidget)===Gtk::RESPONSE_YES);
	}

	static public function findStyle($sStylesDir, array $arrGtkrcPattern=array('/^gtkrc$/i')){
		A::DDIR($sStylesDir);
		A::ISTHESE($arrGtkrcPattern,array('array:string'));
		$arrRet=array();
		$nUnnameStyleIdx=1;
		$oIterator=new IoTreeIterator($sStylesDir, IoIterator::FILE|IoIterator::RETURN_IO);// 创建一个样式树状迭代器
		while(!$oIterator->isDone()){
			$oFile=$oIterator->current();
			foreach($arrGtkrcPattern as $sPattern){
				if(preg_match($sPattern,$oFile->getName())){
					$sStyleNameFile=$oFile->getParentDir().'StyleName.txt';
					if(is_file($sStyleNameFile)){
						$sStyleName=file_get_contents($sStyleNameFile);
					}
					else{
						$sStyleName=G::L('未命名样式 %d','gtk',null,$nUnnameStyleIdx++);
					}
					$arrRet[$sStyleName]=$oFile->getPath();
					break;
				}
			}
			$oIterator->Next();
		}
		return $arrRet;
	}

	static public function openUrlInBrowser($sUrl){
		if(isset($_ENV['OS'])and preg_match('/^windows/i',$_ENV['OS'])){// Windows 平台
			exec("start {$sUrl}");
		}
		else{
			exec("gnome-open {$sUrl}");// 尝试使用 Gnome 环境 中的命名
		}
	}

	static public function startBackgroundWork($nSensitivity=1){
		A::ASSERT_($nSensitivity>=1,G::L('参数 $nSensitivity 不能小于1','gtk'));
		register_tick_function(array(__CLASS__,'checkSignal'));
		declare(ticks=1);
	}

	static public function endBackgroundWork(){
		unregister_tick_function(array(__CLASS__,'checkSignal'));
	}

	static public function block(){
		self::$_bBlocking=true;// 堵塞消息
		register_tick_function(array(__CLASS__,'checkSignal'));// Gtk 处理回调函数
		declare(ticks=1);
		while(self::$_bBlocking){// 检查状态
			if(self::$_arrBackgroupWorkCallback){// 后台任务
				$arrCallback=self::$_arrBackgroupWorkCallback;
				self::$_arrBackgroupWorkCallback=null;
				call_user_func_array($arrCallback,self::$_arrBackgroupWorkArgvs);
			}
		}
		unregister_tick_function(array(__CLASS__,'checkSignal'));
	}

	public function quitBlock(){
		self::$_bBlocking=false;
	}

	static function checkSignal(){
		if(Gtk::events_pending()){// Gtk 视窗信号
			Gtk::main_iteration();
		}
	}

	public function runBackgroupWork($Callback,array $arrArgvs=array()){
		A::CALLBACK($Callback,G::L('参数必须是有效的回调函数','gtk'));
		self::$_arrBackgroupWorkCallback=$Callback;
		self::$_arrBackgroupWorkArgvs=$arrArgvs;
	}

	static public function mapGtkItemToData(GtkTreeModel $oModel,GtkTreeIter $oItem,$MappingData,$sMappingName='unknow'){
		A::STRING($sMappingName);
		$sRealMappingName=$oModel->get_string_from_iter($oItem).'>'.$sMappingName;
		if(self::$_oMapItemToData===null){
			self::$_oMapItemToData=new HasMap();
		}
		return self::$_oMapItemToData->setItem($oModel,$MappingData,$sRealMappingName);
	}

	static public function getGtkItemData(GtkTreeModel $oModel,GtkTreeIter $oItem,$sMappingName='unknow'){
		if(self::$_oMapItemToData===null){
			return null;
		}
		A::STRING($sMappingName);
		$sRealMappingName=$oModel->get_string_from_iter($oItem).'>'.$sMappingName;
		return self::$_oMapItemToData->get($oModel,$sRealMappingName);
	}

	static public function isPhpGtk2(){
		return defined("GObject::TYPE_STRING");
	}

	static public function getGtkVersion(){
		$sVersion=Gtk::get_version();
		$sVersion=str_replace('Gtk','',$sVersion);
		$sVersion=trim($sVersion);
		return $sVersion;
	}

}
